// Regulator.h: interface for the Regulator class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_REGULATOR_H__3C4D86DC_869D_11D1_93E3_006097737B41__INCLUDED_)
#define AFX_REGULATOR_H__3C4D86DC_869D_11D1_93E3_006097737B41__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace std;
//#define LARGESIZE 10000

class Regulator  
{
public:
	void BadStep();
	void GoodStep();
	void SetTarget(double &SL);
//	void PrintResults(char name[]);
	void PrintOpenNewFile(char name[]);
	void ResetAll();

	Regulator();
	Regulator(double &lProp);
	virtual ~Regulator() { outfile.close();}

	// for printing out data to frac.cssr
	// (not good programming)
  // & = pass by reference
	void GetAcceptAndTotal(int &accept, int &total)
	{
		accept = NSuccess; total = NResult;
	}

private:
	double	*StepLength;
	int		NumConsecBadStep, NResult;
	
	int NSuccess;   // to achieve something success rate (number of success)

  double mProp;   // the target percentage of failures (what we aim for)

  // regulate the size of the time-step so that there is a mProp percentage of successes and failures (i.e. if
  // mProp = 50% then there is 50% chance of success or failure)
  void	Monitor(int Result); 

	void	Reset();

	ofstream outfile;
};

inline void Regulator::ResetAll()
	{	
	Reset();
	NResult = 0;
	NSuccess = 0;
	}

// Resets the number of consecutive bad steps
inline void Regulator::Reset()
	{	
	NumConsecBadStep = 0;		
	}

// The value which is entered as an argument is
// defined to be the StepLength.
inline void Regulator::SetTarget(double &SL)
	{	
	StepLength = &SL;
	}

inline Regulator::Regulator()
	{
	StepLength = NULL;
	ResetAll();
	//outfile.open("output/regulator1.out");
	}

  // set the procentage number of not accepted trajectories (i.e. metropolis=false)
  // that you want = 1 - Nsuccess/Ntotal
  inline Regulator::Regulator(double &lProp) : mProp(lProp)
	{	
  StepLength = NULL;
	ResetAll();
	//outfile.open("output/regulator1.out");
	}

  // if a successful trajectory has been found then we check that
  // the timestep is appropriate
inline void Regulator::GoodStep()
	{		
	Reset();
	NSuccess++;
	Monitor(1);
	}

  // if an unsuccessful trajector has been found then we check that
  // the timestep is appropriate.
inline void Regulator::BadStep()
{
	NumConsecBadStep++;
	if(5==NumConsecBadStep && NSuccess == 0) 
	//if(5==NumConsecBadStep) 
	{
		(*StepLength) /= 2.0;
		Reset();
	}
	Monitor(0);
}



/*
inline void Regulator::PrintResults(char name[])
	{
	outfile.close();
	outfile.open(name);

	outfile << "\n\nHow each StepLenth performed:\n\n";

	outfile << "itt" << "\t" << "Step Length" << "\t" << "Pass/Fail" << endl;
	outfile << "_________________________________\n";

	for(int n=0;n<NResult;n++)
		{
		outfile << n << "\t" << StoreStepLength[n];
		switch(StoreResults[n])
			{
			case 0:
				outfile << "\tFail" << endl;
				break;
			default:
				outfile << "\tPass" << endl;
				break;
			}
		}
	outfile << endl << endl;
	}*/

#endif // !defined(AFX_REGULATOR_H__3C4D86DC_869D_11D1_93E3_006097737B41__INCLUDED_)
